import turtle


# Line class

class Line:

    def __init__(self, x1=0, y1=0, x2=0, y2=0, color='green', line_type='solid', thickness=1, content=''):

        self.x1 = x1

        self.y1 = y1

        self.x2 = x2

        self.y2 = y2
        self.color = color

        self.line_type = line_type

        self.thickness = thickness
        self.content = content

        self.dot_in_line = []
        


    # draw line in canvas

    def draw(self):
        t.penup()

        t.goto(self.x1, self.y1)   


        t.pendown()     

        t.pencolor('red')

        t.dot(12)
        self.dot_in_line.append(t.pos())

        t.pencolor(self.color)

        t.pensize(self.thickness)

        if self.line_type == 'dashed':

            t.setundobuffer(None)

            t.pendown()

            t.pendown()

            t.pendown()

            t.pendown()
            t.penup()
            t.penup()
            t.penup()
            t.penup()

            t.pendown()

            t.pendown()

            t.pendown()

            t.pendown()
            t.penup()
            t.penup()
            t.penup()
            t.penup()

        t.goto(self.x2, self.y2)


        t.pencolor('red')

        t.dot(12)
        self.dot_in_line.append(t.pos())


    # add annotate for line object

    def annotate(self, x_offset=0, y_offset=0, angle=0, font_size=10, font_color='black', font_name='Arial'):

        oldx, oldy = t.pos()
        t.penup()

        x = (self.x1 + self.x2) / 2 + x_offset

        y = (self.y1 + self.y2) / 2 + y_offset

        t.goto(x, y)

        t.pendown()
        t.pencolor(font_color)

        t.write(self.content, align='center', font=(font_name, font_size, 'normal'))
        t.penup()

        t.goto(oldx, oldy)


    # 

    def sep_by_item(self, item, scale):

        self.x1, self.y1= t.pos()

        self.x2, self.y2= self.x1 + item[1]*scale, self.y1

        self.content = f'{item[0]}\n{item[1]}万元'


def update_amount_by_price(item, price, element):

    area = element[item][1]

    amount = int(area * price / 10000)

    element[item] = (amount, area)
    return element


def get_price(item, income):

    amount = income[item][0]

    area = income[item][1]

    return round(amount * 10000 / area,0)


def get_amount_for_eachitem(income):

    return [(item[0], item[1][0]) for item in income.items()]


def get_width_and_sep(income, percent=0.02):

    len = sum([item[1] for item in get_amount_for_eachitem(income)]) 

    sep = int(len * percent)

    return sep + len + sep, sep  


def draw_account_element(el, lc):

    '''

    to draw a continuous line for provided a financial accounting element


    el - dist: financial accounting element, eg. income, cost, expenses etc.

    lc - str: color of line

    '''

    points = []


    items = get_amount_for_eachitem(el)
    i = 0

    thickness = 8

    for item in items:
        

        y_offsets = [-45, 15]

        idx = i % 2

        line = Line(color=lc)

        line.thickness = thickness

        line.sep_by_item(item, scale)

        line.draw()

        line.annotate(font_color='black', font_name='heiti', y_offset=y_offsets[idx])

        # thickness -= 2

        i += 1
        points.append(line.dot_in_line)
    
    return points


def move_start_point(x_offset, y_offset, x_origin=0, y_origin=0):

    x = x_origin + x_offset

    y = y_origin + y_offset
    t.penup()

    t.goto(x,y)

    t.pendown()


# 已知条件：

income = {
    '已售住宅': (110198, 97889.4),
    # '未售住宅': (15341, 17602.27),
    # '未售商铺': (5255, 11455.34),
    '已发生利息结余': (650, 0),
    # '未发生利息结余': (200, 0),
}

## 调整单价

# income = update_amount_by_price('未售住宅', 8500, income)


cost = {
    '土地成本': (4998, 0),
    # '开发成本': (85733, 0),
    '已发生开发成本':(66712,0),
    # '未发生开发成本':(19021,0),
    # '管理费用': (4420, 0),
    '已发生管理费用':(2229,0),
    # '未发生管理费用':(2191,0),
    # '营销费用': (5861, 0),
    '已发生营销费用':(4616,0),
    # '未发生营销费用':(1245,0),
    # '营业税金': (11060,0), 
    '已发生营业税金':(1410,0),   
    # '未发生营业税金':(9650,0),

}


## 左右边距占比

sep_perc = 0.03

## 窗体尺寸

w_width = 1400

w_height = 600

## 速度

SLOWER = 1

MID = 5

FASTER = 10

# 结束已知条件



# 计算窗体参数

## 图形宽度， 左右边距

width, sep = get_width_and_sep(income, sep_perc)

## 缩放比例

scale = 10800 / width

width, sep = width*scale, round(sep*scale,0)

## 窗体坐标

left_bottom_x = -sep

left_bottom_y = -100

right_top_x = width-sep

right_top_y = 500

# 结束计算窗体参数



# create a turtle object

t = turtle.Turtle()


# set the size of the turtle window

turtle.setup(width=w_width, height=w_height)


# set the coordinates of the turtle window

turtle.setworldcoordinates(left_bottom_x, left_bottom_y, right_top_x, right_top_y)


# set the speed of the turtle

t.speed(MID)


# ************** 主程序 ************** 


# 收入线

# specific start point

move_start_point(0, 0)

income_points = draw_account_element(el=income, lc='green')


# 成本线

move_start_point(0, 100)

cost_points = draw_account_element(el=cost, lc='orange')

# 绘制垂直网格线
x_of_vertical_lines = sorted(
    list(
        set(

            [p[0][0] for p in income_points] 

            + [income_points[-1][-1][0]]

            + [p[0][0] for p in cost_points]

            + [cost_points[-1][-1][0]]
        )
    )
)

for x in x_of_vertical_lines:

    t.pensize(1)

    t.pencolor('gray')
    t.penup()

    t.goto(x, left_bottom_y)

    t.pendown()

    t.goto(x, right_top_y)

# 绘制收入成本差异线
start = income_points[-1][-1]
end = cost_points[-1][-1]
distance = start[0]-end[0]

move_start_point(0, 200, start[0], start[1])
t.pencolor('red')
t.pensize(3)
t.seth(180)
t.forward(distance)
t.right(165)
t.fd(40)
t.bk(40)
t.right(30)
t.fd(40)
t.bk(40)
t.left(15)
t.penup()
t.fd(distance/2)
t.left(90)
t.fd(15)
t.pencolor('black')
t.pendown()

income_amount = sum([item[1] for item in get_amount_for_eachitem(income)])
cost_amount = sum([item[1] for item in get_amount_for_eachitem(cost)]) 
print(f'收入：{income_amount}万元, 成本：{cost_amount}万元')
diff = income_amount - cost_amount
content = f'差异：{diff}万元 \n占收入比重：{round(diff/income_amount*100,2)}%'
t.write(content, align='center', font=('heiti', 16, 'normal'))
# hide turtle when done

t.hideturtle()

turtle.mainloop()

turtle.done()

